using Sage.Http.Authentication;
using Sage.Http.Models;

namespace Sage.Http.Core
{
    /// <summary>
    /// HTTP请求管理器接口，定义了HTTP请求的核心操作
    /// </summary>
    public interface IHttpRequestManager : IDisposable, IAsyncDisposable
    {
        /// <summary>
        /// 获取基地址
        /// </summary>
        Uri? BaseAddress { get; }

        /// <summary>
        /// 创建HTTP请求构建器
        /// </summary>
        /// <param name="method">HTTP方法</param>
        /// <param name="url">请求URL</param>
        /// <returns>HTTP请求构建器</returns>
        HttpRequestBuilder CreateRequest(HttpMethod method, string url);

        /// <summary>
        /// 创建HTTP请求构建器，使用HttpRouteInfo对象指定API信息
        /// </summary>
        /// <param name="routeInfo">API路由信息</param>
        /// <returns>HTTP请求构建器</returns>
        HttpRequestBuilder CreateRequest(HttpRouteInfo routeInfo);

        /// <summary>
        /// 异步发送 HTTP 请求
        /// </summary>
        /// <param name="method">HTTP 方法</param>
        /// <param name="url">请求的 URL</param>
        /// <param name="queryParams">查询参数，可选</param>
        /// <param name="body">请求体内容，可选</param>
        /// <param name="bodyType">请求体类型，默认为 JSON</param>
        /// <param name="headers">请求头，可选</param>
        /// <param name="cancellationToken">取消令牌，可选</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> SendAsync(
            HttpMethod method,
            string url,
            Dictionary<string, object>? queryParams = null,
            string? body = null,
            BodyType bodyType = BodyType.Json,
            Dictionary<string, object>? headers = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送 HTTP 请求，使用 HttpRouteInfo 对象指定 API 信息
        /// </summary>
        /// <param name="routeInfo">API 路由信息</param>
        /// <param name="queryParams">查询参数字典，可选</param>
        /// <param name="body">请求体内容，可选</param>
        /// <param name="bodyType">请求体类型，默认 JSON</param>
        /// <param name="headers">请求头字典，可选</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> SendAsync(
            HttpRouteInfo routeInfo,
            Dictionary<string, object>? queryParams = null,
            string? body = null,
            BodyType bodyType = BodyType.Json,
            Dictionary<string, object>? headers = null,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送GET请求
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> GetAsync(string requestUri, CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送GET请求并返回字符串内容
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>响应内容的字符串表示</returns>
        Task<string> GetStringAsync(string requestUri, CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送POST请求
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="content">请求内容</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> PostAsync(string requestUri, HttpContent content, CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送PUT请求
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="content">请求内容</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> PutAsync(string requestUri, HttpContent content, CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送DELETE请求
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> DeleteAsync(string requestUri, CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步发送PATCH请求
        /// </summary>
        /// <param name="requestUri">请求URI</param>
        /// <param name="content">请求内容</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>HTTP响应消息</returns>
        Task<HttpResponseMessage> PatchAsync(string requestUri, HttpContent content, CancellationToken cancellationToken = default);

        /// <summary>
        /// 更新基地址
        /// </summary>
        /// <param name="newUrl">新地址</param>
        /// <returns>是否成功更新</returns>
        bool UpdateBaseAddress(Uri newUrl);

        /// <summary>
        /// 更新基地址
        /// </summary>
        /// <param name="newUrl">新地址</param>
        /// <param name="errorMessage">修改失败的错误原因</param>
        /// <returns>是否成功更新</returns>
        bool UpdateBaseAddress(Uri newUrl, out string errorMessage);

        /// <summary>
        /// 更新超时时间
        /// </summary>
        /// <param name="newTimeout">新时间</param>
        /// <returns>是否成功更新</returns>
        bool UpdateTimeout(TimeSpan newTimeout);

        /// <summary>
        /// 更新超时时间
        /// </summary>
        /// <param name="newTimeout">新时间</param>
        /// <param name="errorMessage">修改失败的错误原因</param>
        /// <returns>是否成功更新</returns>
        bool UpdateTimeout(TimeSpan newTimeout, out string errorMessage);

        /// <summary>
        /// 设置默认认证提供者，将应用于所有请求
        /// </summary>
        /// <param name="authProvider">认证提供者</param>
        void SetDefaultAuthentication(IAuthenticationProvider authProvider);

        /// <summary>
        /// 设置Bearer Token认证
        /// </summary>
        /// <param name="token">认证令牌</param>
        /// <param name="scheme">认证方案，默认为"Bearer"</param>
        void SetBearerToken(string token, string scheme = "Bearer");

        /// <summary>
        /// 设置Basic认证
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        void SetBasicAuth(string username, string password);

        /// <summary>
        /// 设置API Key认证
        /// </summary>
        /// <param name="apiKey">API密钥</param>
        /// <param name="parameterName">参数名称</param>
        /// <param name="location">密钥位置</param>
        void SetApiKey(string apiKey, string parameterName, ApiKeyLocation location = ApiKeyLocation.Header);
    }
}